home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / sml_nj / 93src.lha / src / hppa / hppadepend.sml < prev    next >
Encoding:
Text File  |  1993-01-27  |  8.3 KB  |  255 lines

  1. (* Copyright 1992 Scott Draves *)
  2.  
  3. structure HppaInstr =
  4.     struct
  5.     open HppaInstrSet
  6.  
  7.     val error = ErrorMsg.impossible
  8.     val branchDelayedArch = true
  9.     val nop = i_nop
  10.  
  11.     datatype 'label info = INFO of {addrOf: 'label -> int, 
  12.                     nameOf: 'label -> string}
  13.  
  14.     datatype 'label EA =
  15.         Direct of register
  16.       | FDirect of fregister
  17.       | Immed of int
  18.       | ImmedLab of 'label
  19.  
  20.     datatype ikind = IK_NOP | IK_JUMP | IK_INSTR
  21.  
  22.     fun instrKind i_nop        = IK_NOP
  23.       | instrKind (i_bl     _) = IK_JUMP
  24.       | instrKind (i_gate   _) = IK_JUMP
  25.       | instrKind (i_blr    _) = IK_JUMP
  26.       | instrKind (i_bv     _) = IK_JUMP
  27.       | instrKind (i_movb   _) = IK_JUMP
  28.       | instrKind (i_movib  _) = IK_JUMP
  29.       | instrKind (i_combt  _) = IK_JUMP
  30.       | instrKind (i_combf  _) = IK_JUMP
  31.       | instrKind (i_comibt _) = IK_JUMP
  32.       | instrKind (i_comibf _) = IK_JUMP
  33.       | instrKind (i_addbt  _) = IK_JUMP
  34.       | instrKind (i_addbf  _) = IK_JUMP
  35.       | instrKind (i_addibt _) = IK_JUMP
  36.       | instrKind (i_addibf _) = IK_JUMP
  37.       | instrKind (i_bvb    _) = IK_JUMP
  38.       | instrKind (i_bb     _) = IK_JUMP
  39.       | instrKind (i_sdi_bl _) = IK_JUMP
  40.       | instrKind (i_sdi_bb _) = IK_JUMP
  41.       | instrKind (i_sdi_comb _) = IK_JUMP
  42.       | instrKind (i_nullified i) = instrKind i
  43.       | instrKind _            = IK_INSTR
  44.  
  45.  
  46.     fun mayNeedNop i = if IK_JUMP = instrKind(i) then 1 else 0
  47.     fun needsNop _ = 0
  48.  
  49.  
  50.     val base_reg = REG 24
  51.     (* XXX val base_reg_bias = 8192 - 4 *)
  52.  
  53.     datatype 'label sdi =
  54.         (* base_reg = register - label *)
  55.         set_base_reg of 'label * register
  56.  
  57.       (* register = label + int *)
  58.       | load_addr of 'label * int * register
  59.  
  60.       (* register = mem[label + int] *)
  61.       | load  of 'label * int * register
  62.  
  63.       (* fregister = mem[lable + int] and a temp *)
  64.       | loadf of 'label * fregister * register 
  65.  
  66.       (* if arithcond2(register1, register2) then jump *)
  67.       | cbranch of 'label * 'label * arithcond2 * register * register
  68.  
  69.       (* if and(1<<int, register) then jump *)
  70.       | bbranch of 'label * 'label * int * register
  71.  
  72.       (* if fpcond(fregister1, fregister2) then jump *)
  73.       | fbranch of 'label * register
  74.  
  75.       (* register1 = pc; pc +=  label1 - label2 *)
  76.       | jump of 'label * register
  77.  
  78.       (* pc +=  label1 - label2 + register1, register2 is temp,
  79.          not used *)
  80.       | jumpr of 'label * 'label * register * register
  81.  
  82.  
  83.     fun isSdiBranch (cbranch _) = true
  84.       | isSdiBranch (fbranch _) = true
  85.       | isSdiBranch (bbranch _) = true
  86.       | isSdiBranch (jumpr _)   = true
  87.       | isSdiBranch (jump _)    = true
  88.       | isSdiBranch _           = false
  89.  
  90.     fun minSize (set_base_reg _) = 4
  91.       | minSize (load_addr _)    = 4
  92.       | minSize (load _)         = 4
  93.       | minSize (loadf _)        = 20
  94.       | minSize (cbranch _)      = 4
  95.       | minSize (bbranch _)      = 4
  96.       | minSize (fbranch _)      = 4
  97.       | minSize (jump _)         = 4
  98.       | minSize (jumpr _)        = 12
  99.  
  100.     fun offset_estimate (INFO{addrOf,...}, loc) lab =
  101.         ((addrOf lab) - loc - 8) div 4
  102.  
  103.     fun make_jump_offset_expr (lab) =
  104.         le_divn(le_sum(le_diff(le_label(lab), le_dot), le_const(~8)), 4)
  105.  
  106.     fun eval_label_expr (INFO{addrOf, ...}, _) (le_label lab) = addrOf(lab)
  107.       | eval_label_expr info (le_hi21(le)) = hi21(eval_label_expr(info)(le))
  108.       | eval_label_expr info (le_lo11(le)) = lo11(eval_label_expr(info)(le))
  109.       | eval_label_expr info (le_negate(le)) = ~(eval_label_expr(info)(le))
  110.       | eval_label_expr info (le_sum(le1, le2)) =
  111.         (eval_label_expr(info)(le1)) +  (eval_label_expr(info)(le2))
  112.       | eval_label_expr info (le_diff(le1, le2)) =
  113.         (eval_label_expr(info)(le1)) -  (eval_label_expr(info)(le2))
  114.       | eval_label_expr info (le_divn(le, n)) = (eval_label_expr(info)(le)) div n
  115.       | eval_label_expr info (le_const(n)) = n
  116.       | eval_label_expr (_, loc) le_dot = (!loc)
  117.  
  118.  
  119.  
  120.     fun sizeOf (INFO{addrOf,...}) (set_base_reg(lab, _), _) =
  121.         if im14(~(addrOf lab)) then (false, 4) else (true, 8)
  122.  
  123.       | sizeOf (INFO{addrOf,...}) (load_addr(lab, k, _), _) =
  124.         if im14((addrOf lab) + k) then (false, 4) else (true, 8)
  125.  
  126.       | sizeOf (INFO{addrOf,...}) (load(lab, k, _), _) =
  127.         if im14((addrOf lab) + k) then (false, 4) else (true, 8)
  128.  
  129.       | sizeOf (INFO{addrOf,...}) (loadf(lab,k,_), _) = (true,20)
  130.  
  131.       | sizeOf info (cbranch(dest_lab, skip_lab, _, _, _), loc) =
  132.         let val offset = offset_estimate(info, loc)(dest_lab)
  133.         in if im12(offset) then (false, 4)
  134.            else if im17(offset) then (false, 8)
  135.             else (true, 16)
  136.         end
  137.  
  138.       | sizeOf info (fbranch(destLab,tmpR), loc) = let
  139.           val offset = offset_estimate(info,loc) destLab
  140.             in
  141.         if im17 offset then (false,4) else (true,12)
  142.             end
  143.  
  144.       | sizeOf info (bbranch(dest_lab, skip_lab, _, _), loc) = let
  145.             val offset = offset_estimate(info, loc)(dest_lab)
  146.         in 
  147.         if im12(offset) then (false, 4) else (true,8)
  148.         end
  149.  
  150.       | sizeOf info  (jump(dest_lab, _), loc) = let
  151.            val offset = offset_estimate(info, loc)(dest_lab)
  152.         in 
  153.         if im17(offset) then (false, 4) else (true, 12)
  154.         end
  155.  
  156.       | sizeOf info (jumpr(dest_lab, from_lab, _, _), _) =
  157.         (true, 12)
  158.  
  159.     fun expand info (set_base_reg(lab, reg), size, _) =
  160.         let val offset = le_negate(le_label lab)
  161.         in case size of
  162.         4 => [i_sdi_ldo(reg, offset, base_reg)]
  163.           | 8 => [i_sdi_addil(le_hi21(offset), reg),
  164.               i_sdi_ldo(addr_reg, le_lo11(offset), base_reg)]
  165.           | _ => error "[HppaInstr.expand set_base_reg]"
  166.         end
  167.         
  168.       | expand info (load_addr(lab, k, reg), size, _) =
  169.         let val offset = le_sum(le_label(lab), le_const(k))
  170.         in case size of
  171.         4 => [i_sdi_ldo(base_reg, offset, reg)]
  172.           | 8 => [i_sdi_addil(le_hi21(offset), base_reg),
  173.               i_sdi_ldo(addr_reg, le_lo11(offset), reg)]
  174.           | _ => error "[HppaInstr.expand load_addr]"
  175.         end
  176.  
  177.       | expand info (load(lab, k, reg), size, _) =
  178.         let val offset = le_sum(le_label(lab), le_const(k))
  179.         in case size of
  180.         4 => [i_sdi_ldw(base_reg, offset, reg)]
  181.           | 8 => [i_sdi_addil(le_hi21(offset), base_reg),
  182.               i_sdi_ldw(addr_reg, le_lo11(offset), reg)]
  183.           | _ => error "[HppaInstr.expand load]"
  184.         end
  185.  
  186.       | expand info (loadf(lab,freg,tmpR),size,_) = let
  187.            val offset = le_sum(le_label lab,le_const 0)
  188.         in
  189.         case size
  190.           of 20 => [i_sdi_ldil(le_hi21 offset,tmpR),
  191.                 i_sdi_ldo(tmpR,le_lo11 offset,tmpR),
  192.                 i_addl(tmpR,base_reg,never,tmpR),
  193.                 
  194.                 i_fldws(tmpR,0,mab_none,freg,FrLeftHalf),
  195.                 i_fldws(tmpR,4,mab_none,freg,FrRightHalf)]
  196.            | _ => error "loadf"
  197.         end
  198.  
  199.       | expand info (cbranch(dest_lab, skip_lab, cond, r1, r2), size, _) =
  200.         let val offset = make_jump_offset_expr(dest_lab)
  201.         in case size of
  202.         4 => [i_sdi_comb(r1, r2, cond, offset, n_no_nullify)]
  203.           | 8 => [i_sub(r1, r2, invert_cond cond, zero_reg),
  204.               i_sdi_bl(offset, n_no_nullify, zero_reg)]
  205.           | 16 => [i_sdi_comb(r1, r2, invert_cond cond,
  206.                   make_jump_offset_expr(skip_lab),
  207.                   n_no_nullify),
  208.                i_sdi_addil(le_hi21(offset), base_reg),
  209.                i_sdi_ldo(addr_reg, le_lo11(offset), addr_reg),
  210.                i_bv(zero_reg, n_no_nullify, addr_reg)]
  211.                
  212.           | _ => error "[HppaInstr.expand cbranch]"
  213.         end
  214.  
  215.       | expand info (fbranch(destLab,tmpR),size,loc) = let
  216.           val offset = make_jump_offset_expr destLab
  217.         in
  218.         case size 
  219.           of 4  => [i_sdi_bl(offset,n_no_nullify,zero_reg)]
  220.            | 12 => [i_sdi_addil(le_hi21 offset, base_reg),
  221.                 i_sdi_ldo(addr_reg,le_lo11 offset,addr_reg),
  222.                 i_bv(zero_reg,n_no_nullify,addr_reg)]
  223.            | _  => error "[HppaInstr.expand fbranch]" 
  224.         end
  225.  
  226.       | expand info (bbranch(dest_lab, skip_lab, bit, r), size, _) =
  227.         let val offset = make_jump_offset_expr(dest_lab)
  228.         in case size of
  229.         4 => [i_sdi_bb(r, bit, sc_leftmost_one, offset, n_no_nullify)]
  230.           | 8 => [i_sdi_bb(r, bit, sc_leftmost_zero,
  231.                    make_jump_offset_expr(skip_lab), n_no_nullify),
  232.               i_sdi_bl(offset, n_no_nullify, zero_reg)]
  233.           | _ => error "[HppaInstr.expand bbranch]"
  234.         end
  235.  
  236.       | expand info (jump(dest_lab, target), size, _) =
  237.         (case size of
  238.          4 => [i_sdi_bl(make_jump_offset_expr(dest_lab),
  239.                 n_no_nullify, target)]
  240.            | 12 => let val offset = le_label(dest_lab)
  241.                in [i_sdi_addil(le_hi21(offset), base_reg),
  242.                i_sdi_ldo(addr_reg, le_lo11(offset), addr_reg),
  243.                i_bv(zero_reg, n_no_nullify, addr_reg)]
  244.                end
  245.            | _ => error "[HppaInstr.expand jump]")
  246.  
  247.      (* if can guarantee that labels in jump table are 0 mod 8
  248.         then could use i_blr *)
  249.  
  250.       | expand info (jumpr(dest_lab, here_lab, offset, treg), size, _) =
  251.         error "[HppaInstr.expand jumpr]"
  252.     
  253.     end
  254.  
  255.